﻿using System;
using System.Linq;
using System.Collections.Generic;
using Bling.DSL;
using Bling.Core;
using Controls = Microsoft.WindowsAPICodePack.DirectX.Controls;
using Microsoft.WindowsAPICodePack.DirectX.Controls;
using Microsoft.WindowsAPICodePack.DirectX.Direct3D10;
using Microsoft.WindowsAPICodePack.DirectX.Direct3D;
using Microsoft.WindowsAPICodePack.DirectX.DXGI;
using Microsoft.WindowsAPICodePack.DirectX.DirectXUtilities;
using DXUtil = Microsoft.WindowsAPICodePack.DirectX.DirectXUtilities;
using Bling.Vecs;
using Bling.WPF.Custom;
using linq = Microsoft.Linq.Expressions;
using Bling.Linq;
using Bling.Util;
using Bling.Matrices;
using System.Runtime.InteropServices;
using Bling.WPF;
using System.Windows.Controls;
using System.Windows.Interop;

namespace Bling.DX {
  public abstract class HasHost : Canvas, ICanStart {
    private class MyDirectHost : DirectHost {
    }

    private readonly MyDirectHost Host0 = new MyDirectHost();
    public void Start() { if (AlreadyLoaded && ((object)Overlay) != null) Overlay.CurrentValue.Start(); }
    public void Stop() { if (((object)Overlay) != null) Overlay.CurrentValue.Stop(); }
    public FrameworkElementBl Host { get { return ((object)Overlay) != null ? Overlay : Host0.Bl(); } }
    public CanvasBl OverlayContent { get { return Overlay.OverlayContent; } }
    //private RenderDevice Device; //= new RenderDevice();
    private readonly HasOverlayBl Overlay;
    private bool AlreadyLoaded = false;
    public readonly RenderDevice Device = new RenderDevice();

    public HasHost(bool ActivateOverlay) {
      Host0.Bl().LeftTop = new PointBl(0, 0);
      if (ActivateOverlay) {
        Overlay = new HasOverlayBl(this);
        Host0.Bl().Size = Overlay.Size;
        Host0.Bl().CanvasParent = Overlay;
      } else Host.CanvasParent = this.Bl();

      RenderDeviceImpl Device0 = null;
      Host0.Loaded += (x, y) => {
        if (AlreadyLoaded) return;
        AlreadyLoaded = true;
        (Device0 == null).Assert();
        var Size = Host.Size.CurrentValue;
        Device0 = new RenderDeviceImpl(Device, Host0.Handle, new Vec2<uint>() {
          X = (uint)Size.X,
          Y = (uint)Size.Y,
        });
        Device0.InitRender();
        Host0.Render = () => {
          Dispatcher.Invoke(Device0.PreAction, TimeSpan.FromMilliseconds(100));
          Device0.RenderAction();
        };
      };
      Host0.SizeChanged += (x, y) => {
        if (Device0 == null) return;
        var Size = Host.Size.CurrentValue;
        Device0.Resize(new Vec2<uint>() {
          X = (uint)Size.X,
          Y = (uint)Size.Y,
        });
      };

    }
  }



  /*
  public class WPFHost2Bl : CanvasBl<WPFHost2, WPFHost2Bl> {
    public WPFHost2Bl(CanvasBl canvas, PointBl Size, Action<RenderDeviceImpl> RDevice) :
      base(canvas, new WPFHost2(Size, RDevice)) { }
  }
  public class WPFHost2 : Canvas, ICanStart {
    private RenderDeviceImpl Device;
    private D3DImage Host;
    public void Start() { ; }
    public void Stop() { ; }

    public WPFHost2(PointBl Size, Action<RenderDeviceImpl> InitDevice) : base() {
      this.Bl().Size = Size;
      Host = new D3DImage();
      Host.SetBackBuffer(D3DResourceType.IDirect3DSurface9, IntPtr.Zero);

      new ImageBl(this) {
        LeftTop = 0d, Size = Size, Source = Host,
      };
      this.Loaded += (x, y) => {
        Device = new RenderDeviceImpl(new Vec2<uint>() {
          X = (uint)Size.X.CurrentValue,
          Y = (uint)Size.Y.CurrentValue,
        });
        InitDevice(Device);
        Host.SetBackBuffer(D3DResourceType.IDirect3DSurface9, Device.GetHandle());

   * Host.Render = () => {
          Dispatcher.Invoke(Device.PreAction, TimeSpan.FromMilliseconds(100));
          Device.RenderAction();
        };
        Host.Init = true;
      };
    }
  }
*/

}